<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<p>{{name}}</p>
			<p>{{age}}</p>
			<input type="text">
		</div>
		<script type="text/javascript">
			!function (e,w) {
				function Vue (option) {
					Object.assign(this,{
						_data: option.data,
						element: null,
					},option)
					this.init()
				}
				Vue.prototype = {
					init(){
						this.element = e.querySelector(this.el)
						let ob = new Observer(this._data)
						this.comp = new Compile(this.el)
					}
				}
				function Observer (data) {
					this.data = data
					this.init()
				}
				Observer.prototype = {
					init(){
						Object.keys(this.data).forEach(key => {
							this.reactive(this.data,key,this.data[key])
						})
					},
					reactive(data,key,val){
						const {handle} = new Watcher(key)
						Object.defineProperty(data,key,{
							get(){
								console.log(`%c** ${ key }'s getter`,"color:#25a360")
								return val
							},
							set(v){
								if(handle && handle.length !== undefined){
									handle.forEach(h => h(v))
								}
								console.log(`%c** ${ key }'s setter`,"color:#25a360")
								val = v
							}
						})
					}
				}
				function Watcher (key) {
					// 拿到 key 之后, 寻找模板中引用到 key 的地方
					// 向 handle 对象中注入拿 value 修改模板的回调
					this.handle = []
					this.init()
				}
				Watcher.prototype = {
					init(){
						this.handle.push(v => {
							console.log(v)
						})
					}
				}
				function Compile (el) {
					this.init(el)
				}
				Object.assign(Compile.prototype,{
					init(el){
						this.element = e.querySelector(el)
						// console.log("compile in running")
						console.log(Array.from(this.element.childNodes).forEach(n => {
							if(n.nodeType === 1){
								console.log(n)
							}else if(n.nodeType === 3){
								let content = n.nodeValue.trim()
								if(content === ""){
									return false
								}
								console.log("文本节点",content)
							}
						}))
					}
				})
				w.Vue = Vue
			}(document,window)
			const vm = new Vue({
				el: "#app",
				data: {
					name: "Pinkie",
					age: 18
				}
			})
			vm.data.name = "oo"
			
			// ********************************* 分隔
			
			// var appEl = document.querySelector("#app")
			// var _data = {
			// 	name: "Twilight"
			// }
			// var observer = {
			// 	name: "Twilight"
			// }
			// Object.defineProperty(_data,"name",{
			// 	get(){
			// 		console.log("%c** name's getter","color:#25a360")
			// 		return observer.name
			// 	},
			// 	set(v){
			// 		console.log("%c** name's setter","color:#25a360")
			// 		observer.name = v
			// 		update()
			// 	}
			// })
			// var template = `<h2>${ _data.name }</h2>`
			// function update () {
			// 	template = `<h2>${ _data.name }</h2>`
			// 	appEl.innerHTML = template
			// }
			// update()
			// _data.name = "Xiaoming"
			// var reg = /a/
			// console.log(reg.test("123a"))
			// var b = "123a".replace(reg,s => {
			// 	return s + "!"
			// })
			// console.log(b)
		</script>
	</body>
</html>